package it.yuzuojian.com.servlet;

import java.io.*;
import it.yuzuojian.com.ApplicationContext;
import it.yuzuojian.com.handle.mvc.StaticResourceHandle;
import it.yuzuojian.com.pojo.MethodAndObject;
import it.yuzuojian.com.pojo.mvc.ModelAndView;
import it.yuzuojian.com.resolver.InternalResourceViewResolver;
import it.yuzuojian.com.util.DispatcherServletUtil;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.concurrent.ConcurrentHashMap;

public class DispatcherServlet extends HttpServlet {
    private static ConcurrentHashMap<String, MethodAndObject> methods = new ConcurrentHashMap<>();
    private DispatcherServletUtil dispatcherServletUtil = new DispatcherServletUtil();
    private StaticResourceHandle staticResourceHandle = new StaticResourceHandle();

    @Override
    public void init(ServletConfig config) throws ServletException {
        String clazz = config.getInitParameter("clazz");
        Class<?> aClass= null;
        try {
            aClass = Class.forName(clazz);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        if(aClass ==null){
            throw new RuntimeException("无法解析类");
        }
        ApplicationContext applicationContext = new ApplicationContext(aClass);
        super.init(config);
        dispatcherServletUtil.doInit(methods);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String servletPath = request.getServletPath();
        staticResourceHandle.handle(request,response,servletPath);
        MethodAndObject methodAndObject = methods.get(servletPath);
        if (methodAndObject == null) {
            try {
                throw new Exception("没有该对应的映射路径");
            } catch (Exception e) {
                return;
            }
        }
        Method method = methodAndObject.getMethod();
        Object invoke =null;
        ModelAndView modelAndView = new ModelAndView();
        try {
            invoke = method.invoke(methodAndObject.getObject(),dispatcherServletUtil.getParams(request,response,modelAndView,methodAndObject.getMethod()));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        if(invoke instanceof ModelAndView){
            modelAndView=(ModelAndView)invoke;
        }else {
            modelAndView.setView(invoke);
        }
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.resolver(request,response,modelAndView,methodAndObject);
    }
}
